package net.jgrm.common.util;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * Excel工具类，提供通用的Excel导出功能
 *
 * @author system
 */
@Slf4j
public class ExcelUtils {

    /**
     * 导出Excel文件
     *
     * @param response 响应对象
     * @param fileName 文件名（不含后缀）
     * @param dataList 数据列表
     * @param clazz 数据类型
     * @param sheetName 工作表名称
     * @param <T> 数据泛型
     */
    public static <T> void exportExcel(HttpServletResponse response, String fileName, List<T> dataList, Class<T> clazz, String sheetName) {
        try {
            // 设置响应头
            setResponseHeader(response, fileName);
            
            // 使用EasyExcel写入数据
            EasyExcel.write(response.getOutputStream(), clazz)
                    .sheet(sheetName)
                    .doWrite(dataList);
                    
            log.info("Excel导出成功，文件名：{}.xlsx，数据量：{}", fileName, dataList.size());
        } catch (Exception e) {
            log.error("Excel导出失败，文件名：{}.xlsx", fileName, e);
            // 重置响应
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            try {
                response.getWriter().println("{\"code\": 500, \"message\": \"Excel导出失败：" + e.getMessage() + "\"}");
            } catch (IOException ex) {
                log.error("写入错误响应失败", ex);
            }
        }
    }

    /**
     * 设置Excel导出的响应头
     *
     * @param response 响应对象
     * @param fileName 文件名（不含后缀）
     * @throws Exception 异常
     */
    public static void setResponseHeader(HttpServletResponse response, String fileName) throws Exception {
        // 设置内容类型为Excel
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("UTF-8");
        
        // 生成带时间戳的文件名，防止重复
        String fullFileName = fileName + "_" + System.currentTimeMillis() + ".xlsx";
        
        // 对文件名进行URL编码，避免中文乱码
        String encodedFileName = URLEncoder.encode(fullFileName, StandardCharsets.UTF_8.toString()).replaceAll("\\+", "%");
        
        // 设置响应头
        response.setHeader("Content-disposition", "attachment;filename*=UTF-8''" + encodedFileName);
    }

    /**
     * 创建ExcelWriter对象，用于复杂的Excel导出场景
     *
     * @param response 响应对象
     * @param fileName 文件名
     * @param clazz 数据类型
     * @return ExcelWriter对象
     * @throws Exception 异常
     */
    public static <T> ExcelWriter createExcelWriter(HttpServletResponse response, String fileName, Class<T> clazz) throws Exception {
        setResponseHeader(response, fileName);
        return EasyExcel.write(response.getOutputStream(), clazz).build();
    }

    /**
     * 创建WriteSheet对象
     *
     * @param sheetNo 工作表序号
     * @param sheetName 工作表名称
     * @return WriteSheet对象
     */
    public static WriteSheet createWriteSheet(int sheetNo, String sheetName) {
        return EasyExcel.writerSheet(sheetNo, sheetName).build();
    }

    /**
     * 关闭ExcelWriter对象
     *
     * @param excelWriter ExcelWriter对象
     */
    public static void closeExcelWriter(ExcelWriter excelWriter) {
        if (excelWriter != null) {
            excelWriter.finish();
        }
    }
}